﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System.ServiceModel;
using System.Web.Services.Protocols;
using Microsoft.Xrm.Sdk.Messages;

namespace Microsoft.IT.Crm.Utility.CrmSolutionManager
{
    class XrmEntityService
    {
        /// <summary>
        /// Get all the entities with the input entity name.
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="entityKey"></param>
        /// <returns></returns>
        public static IList<Entity> GetAllEntities(string entity, string[] fields)
        {
            if (string.IsNullOrEmpty(entity)) return null;

            try
            {
                QueryExpression query = new QueryExpression()
                {
                    Distinct = false,
                    EntityName = entity,
                    ColumnSet = new ColumnSet(fields),
                    Criteria =
                    {
                        Filters = 
                        {
                            new FilterExpression
                            {
                                Conditions = 
                                {
                                }
                            }
                        }
                    }
                };

                return XrmServiceHelper.OrganizationService.RetrieveMultiple(query).Entities;
            }
            catch (FaultException<OrganizationServiceFault>)
            {
                throw;
            }

            catch (SoapException)
            {
                throw;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// Retrieve the entities according to the condition filter.
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="fields"></param>
        /// <param name="conditionField"></param>
        /// <param name="conditionValue"></param>
        /// <returns></returns>
        public static DataCollection<Entity> RetrieveMultipleEntity(string entity, string[] fields, string conditionField, string conditionValue)
        {
            if (string.IsNullOrEmpty(entity)) return null;
            if (string.IsNullOrEmpty(conditionField) || string.IsNullOrEmpty(conditionValue)) return null;

            try
            {
                QueryExpression query = new QueryExpression()
                {
                    Distinct = false,
                    EntityName = entity,
                    ColumnSet = new ColumnSet(fields),
                    Criteria =
                    {
                        Filters = 
                        {
                            new FilterExpression
                            {
                                Conditions = 
                                {
                                    new ConditionExpression(conditionField, ConditionOperator.BeginsWith, conditionValue),
                                    new ConditionExpression(conditionField, ConditionOperator.EndsWith, conditionValue)
                                },
                                FilterOperator = LogicalOperator.Or
                            }
                        }
                    }
                };

                var entities = XrmServiceHelper.OrganizationService.RetrieveMultiple(query).Entities;
                return entities;
            }
            catch (FaultException<OrganizationServiceFault>)
            {
                throw;
            }

            catch (SoapException)
            {
                throw;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// Retrieve the entities, and get the first entity according to the condition filter.
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="fields"></param>
        /// <param name="conditionField"></param>
        /// <param name="conditionValue"></param>
        /// <returns></returns>
        public static Entity RetrieveEntity(string entity, string[] fields, string conditionField, string conditionValue)
        {
            var entities = RetrieveMultipleEntity(entity, fields, conditionField, conditionValue);
            if (entities.Count > 0)
                return entities[0];
            else
                return null;
        }

        public static void UpdateEntity(Entity entity)
        {
            if (entity == null) return;

            try
            {
                XrmServiceHelper.OrganizationService.Update(entity);
            }
            catch (FaultException<OrganizationServiceFault>)
            {
                throw;
            }

            catch (SoapException)
            {
                throw;
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
